Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Add fluid columns width support #480

Merged
merged 25 commits into from
Nov 4, 2020

Conversation

DanailH
Copy link
Member

@DanailH DanailH commented Oct 21, 2020

This PR aims to provide support for fluid / responsive columns. This is achieved by setting a flex property on a column definition. The flex property can work together with the width property.

I've tested a couple of data grids to benchmark the functionality and the one that seemed the most intuitive was the one that ag-Grid provides.

The default functionality is not affected by this change. The fluid columns will only work if a user sets the flex optional property in the column definition.

Limitations: Currently if you resize a column with flex and you resize the entire page the sizes of all columns are returned to their original state (this is also the current behavior)

PS: Although this solution works if we decide to go with a different public API I will change it.

Fixes #347

@DanailH DanailH self-assigned this Oct 21, 2020
Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amiranga Does the new API solve your problem? You can preview the documentation at https://deploy-preview-480--material-ui-x.netlify.app/components/data-grid/columns/#column-fluid-width


@DanailH for the test side, this feature sounds like a (rare?) case where we could leverage unit tests on the width computation logic rather than using a full end-to-end suite. We could probably have one smoke end to end test in karma (we need to make sure the widths in pixels are correct, screenshots would be bad, and we don't need to have interactions), and cover the edge cases with unit tests? I wonder 🤔

docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 21, 2020

We would need to change the demo or introduce the concept of minWidth, the first column is unusable:

(or at least have #416 😁)

@oliviertassinari oliviertassinari added component: data grid This is the name of the generic UI component, not the React module! new feature New feature or request labels Oct 21, 2020
@DanailH
Copy link
Member Author

DanailH commented Oct 22, 2020

We would need to change the demo or introduce the concept of minWidth, the first column is unusable:

(or at least have #416 😁)

Yes, I agree with this and we can easily bump the minWidth. Currently its at 50px we can make it a bit bigger than that, what do you think @oliviertassinari ?

@DanailH
Copy link
Member Author

DanailH commented Oct 22, 2020

@amiranga Does the new API solve your problem? You can preview the documentation at https://deploy-preview-480--material-ui-x.netlify.app/components/data-grid/columns/#column-fluid-width

@DanailH for the test side, this feature sounds like a (rare?) case where we could leverage unit tests on the width computation logic rather than using a full end-to-end suite. We could probably have one smoke end to end test in karma (we need to make sure the widths in pixels are correct, screenshots would be bad, and we don't need to have interactions), and cover the edge cases with unit tests? I wonder 🤔

Sounds like a plan. The unit tests will check if the width of the columns is calculated correctly after rendering the grid. After all the column calculation when the flex is set is a linear formula with 1 unknown.

I'm more concerned about what should we do about the minWidth. How it currently works is that I'm taking the sum of the widths of all columns that DOES NOT have flex (which by default is 100 px) set and if the sum is more or equal to the total grid width the width of the columns that have flex defaults to the base value of 100 px and a scroll may appear (depends on the total size). If on the other hand, the sum of the width of the columns is less than the width of the grid then the available space is distributed among the columns that do have flex set. That's why in the end some columns with flex may end up with a width of 10px for example. But I can also argue that this is something that can be handled externally.

If we would want to introduce a minWidth property on a column configuration I would suggest creating a separate ticket for it because we would also need to handle the case with the useColumnResize, what do you think @oliviertassinari @dtassone ?

@oliviertassinari
Copy link
Member

@DanailH Interesting, better ask insights from @dtassone.

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, I have noticed a bug with the hover logic (persistence of hover state on mobile) can be fixed with:

diff --git a/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts b/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts
index fbe307c2..4e0f7bae 100644
--- a/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts
+++ b/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts
@@ -126,6 +126,10 @@ export const useStyles = makeStyles(
           cursor: 'col-resize',
           '&:hover, &.Mui-resizing': {
             color: theme.palette.text.primary,
+            // Reset on touch devices, it doesn't add specificity
+            '@media (hover: none)': {
+              color: borderColor,
+            },
           },
         },
         '& .MuiDataGrid-iconSeparator': {

packages/grid/_modules_/grid/hooks/root/useColumns.ts Outdated Show resolved Hide resolved
packages/grid/_modules_/grid/models/colDef/colDef.ts Outdated Show resolved Hide resolved
packages/grid/_modules_/grid/hooks/root/useColumns.ts Outdated Show resolved Hide resolved
@DanailH
Copy link
Member Author

DanailH commented Oct 28, 2020

Unrelated, I have noticed a bug with the hover logic (persistence of hover state on mobile) can be fixed with:

diff --git a/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts b/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts
index fbe307c2..4e0f7bae 100644
--- a/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts
+++ b/packages/grid/_modules_/grid/components/styled-wrappers/GridRootStyles.ts
@@ -126,6 +126,10 @@ export const useStyles = makeStyles(
           cursor: 'col-resize',
           '&:hover, &.Mui-resizing': {
             color: theme.palette.text.primary,
+            // Reset on touch devices, it doesn't add specificity
+            '@media (hover: none)': {
+              color: borderColor,
+            },
           },
         },
         '& .MuiDataGrid-iconSeparator': {

Done

@dtassone
Copy link
Member

dtassone commented Oct 30, 2020

Missing storybook stories. Behaviour with many cols, with just a few...
What happens when we resize the grid?

What happens if we resize the cols?

@@ -16,14 +16,47 @@ import { useApiMethod } from '../../root/useApiMethod';
import { Logger, useLogger } from '../../utils/useLogger';
import { useGridState } from '../core/useGridState';

function mapColumns(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be selector?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep it as it is. This function is only used in the hydrateColumns one and initially, that functionality was part of the hydrateColumns but I separated it from it because the hydrateColumns was becoming a bit too bloated.

docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
docs/src/pages/components/data-grid/columns/columns.md Outdated Show resolved Hide resolved
packages/grid/data-grid/src/DataGrid.test.tsx Outdated Show resolved Hide resolved
@DanailH
Copy link
Member Author

DanailH commented Nov 4, 2020

Should I merge this or should I wait for everyone to approve? @mbrookes @dtassone

@dtassone
Copy link
Member

dtassone commented Nov 4, 2020

Should I merge this or should I wait for everyone to approve? @mbrookes @dtassone

Thanks for waiting. ATM I would say, wait for the approval of Olivier and me, please :)

I always do that's why I'm asking 😋

@DanailH DanailH merged commit 4cbde43 into mui:master Nov 4, 2020
@@ -115,7 +149,7 @@ const getUpdatedColumnState = (
export function useColumns(columns: Columns, apiRef: ApiRef): InternalColumns {
const logger = useLogger('useColumns');
const [gridState, setGridState, forceUpdate] = useGridState(apiRef);

const viewportWidth = gridState.containerSizes ? gridState.containerSizes.viewportSize.width : 0;
Copy link
Member

@oliviertassinari oliviertassinari Nov 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that it would be better to keep the same name for variables, const containerWidth would match its usage.

oliviertassinari added a commit that referenced this pull request Nov 6, 2020
dtassone pushed a commit to dtassone/material-ui-x that referenced this pull request Nov 9, 2020
* [DataGrid] Add fluid columns width support

* Fix doc formatting

* Fix documentation so that it is complient to the MUI documentation standarts

* Add unit tests

* Update packages/grid/_modules_/grid/hooks/root/useColumns.ts

Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>

* Update packages/grid/_modules_/grid/models/colDef/colDef.ts

Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>

* Fix PR comments

* Fix unit tests

* Resolve TS issues

* Add // @ts-expect-error need to migrate helpers to TypeScript before toHaveInlineStyle

* Add storybook examples

* Update docs/src/pages/components/data-grid/columns/columns.md

Co-authored-by: Matt <github@nospam.33m.co>

* Update docs/src/pages/components/data-grid/columns/columns.md

Co-authored-by: Matt <github@nospam.33m.co>

* Update docs/src/pages/components/data-grid/columns/columns.md

Co-authored-by: Matt <github@nospam.33m.co>

* Update docs/src/pages/components/data-grid/columns/columns.md

Co-authored-by: Matt <github@nospam.33m.co>

* Update docs/src/pages/components/data-grid/columns/columns.md

Co-authored-by: Matt <github@nospam.33m.co>

* Update packages/grid/data-grid/src/DataGrid.test.tsx

Co-authored-by: Matt <github@nospam.33m.co>

* Fix storybook flex col width examples

* rerun ci

* Fix formatting

* Update docs/src/pages/components/data-grid/columns/columns.md

* Trigger CI

Co-authored-by: Olivier Tassinari <olivier.tassinari@gmail.com>
Co-authored-by: Matt <github@nospam.33m.co>
dtassone pushed a commit to dtassone/material-ui-x that referenced this pull request Nov 9, 2020
@AleKrabbe
Copy link

Sorry to be asking this here, but it seems related. Is there some sort of solution to make the XGrid table responsive by setting column priorities so that they get hidden based on their priority and width of the screen?

Here is an example: http://www.primefaces.org:8080/showcase/ui/data/datatable/responsive.xhtml?jfwid=2d38a

@oliviertassinari
Copy link
Member

@AleKrabbe Please open a new issue, it's not related to this effort. Currently, you can implement this with the useMediaQuery helper to match specific breakpoints.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DataGrid] Columns to have a fluid width
5 participants